package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.LuckyNumberVo;
import com.ruoyi.system.domain.vo.MemberPackageVo;
import com.ruoyi.system.domain.vo.MemberSearchVo;
import com.ruoyi.system.dto.MemberPackageDTO;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IMemberItemService;
import com.ruoyi.system.service.IMemberService;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
public class MemberServiceImpl extends ServiceImpl<MemberPackageConfigMapper, MemberPackageConfig> implements IMemberService {
    @Autowired
    private IMemberItemService memberItemService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private LuckyNumberMapper luckyNumberMapper;

    @Autowired
    private AddFriendMapper addFriendMapper;

    @Autowired
    private GroupAssistantMapper groupAssistantMapper;

    @Autowired
    private PCMapper pcMapper;

    @Autowired
    private TUserMapper userMapper;


    @Override
    @Transactional
    public Boolean addOrUpdate(MemberPackageVo memberPackageVo) {
        // 新增
        MemberPackageConfig memberPackageConfig = new MemberPackageConfig();
        BeanUtils.copyProperties(memberPackageVo, memberPackageConfig);
        if (memberPackageVo.getId() != null){
            return transactionTemplate.execute(e -> {
                // 修改
                baseMapper.updateById(memberPackageConfig);
                if (!memberPackageVo.getPackageItems().isEmpty()){
                    // 先将之前的id改为无效再新增
                    memberItemService.updateByConfig(memberPackageVo.getPackageItems(), memberPackageVo.getId());
                }return Boolean.TRUE;
            });
        }else {
            return transactionTemplate.execute(e -> {
                baseMapper.insert(memberPackageConfig);
                // 新增套餐项
                memberItemService.addMemberItemList(memberPackageVo.getPackageItems(), memberPackageConfig.getId());
                return Boolean.TRUE;
            });
        }
    }

    @Override
    public List<MemberPackageDTO> getList(MemberSearchVo searchVo) {
        List<MemberPackageConfig> memberPackageConfigs = baseMapper.selectList(new LambdaQueryWrapper<MemberPackageConfig>()
                .eq(searchVo.getState() !=null , MemberPackageConfig::getState, searchVo.getState())
                .eq(searchVo.getPackageType() != null, MemberPackageConfig::getPackageType, searchVo.getPackageType())
                .and(searchVo.getPackageName()!= null && !searchVo.getPackageName().isEmpty(), w1 -> w1.like(MemberPackageConfig::getPackageName, searchVo.getPackageName()))
            .orderByDesc(MemberPackageConfig::getCreateTime));
        List<MemberPackageDTO> dtos = new ArrayList<>();
        for (MemberPackageConfig memberPackageConfig : memberPackageConfigs) {
            MemberPackageDTO memberPackageDTO = new MemberPackageDTO();
            BeanUtils.copyProperties(memberPackageConfig, memberPackageDTO);
            memberPackageDTO.setPackageItems(memberItemService.getListByConfigId(memberPackageConfig.getId()));
            dtos.add(memberPackageDTO);
            if (searchVo.getUserId() != null){
                // 查询该用户到期时间
                memberPackageDTO.setExpireTime(getExpireTime(memberPackageConfig.getPackageType(), searchVo.getUserId()));
            }
          }
        return dtos;
    }

    private String getExpireTime(Integer packageType,String userId) {
        // 查询用户信息
        TUser tUser = userMapper.getByUid(userId);
        // 查询用户到期时间 
        switch (packageType){
            case 1:
                // 普通 -加好友 addFriend
                AddFriend addFriend = addFriendMapper.selectOne(new LambdaQueryWrapper<AddFriend>().eq(AddFriend::getOwnerId, tUser.getUid()).orderByDesc(AddFriend::getEndTime).last("limit 1"));
                if (addFriend != null){
                    LocalDate endTime = addFriend.getEndTime();
                    if (endTime != null){
                        return endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    }
                    return "9999-99-99";
                }
                break;
            case 2:
                //  高级 - pc 
                PCLogin pc = pcMapper.selectOne(new LambdaQueryWrapper<PCLogin>().eq(PCLogin::getOwnerId, tUser.getUid()).orderByDesc(PCLogin::getEndTime).last("limit 1"));
                if (pc != null){
                    if (pc.getEndTime() != null){
                        return pc.getEndTime();
                    }
                    return "9999-99-99";
                }
                break;
            case 3:
                // 超级 - 群
                GroupAssistant groupAssistant = groupAssistantMapper.selectOne(new LambdaQueryWrapper<GroupAssistant>().eq(GroupAssistant::getOwnerId, tUser.getId()).orderByDesc(GroupAssistant::getEndTime).last("limit 1"));
                if (groupAssistant != null){
                    LocalDateTime endTime = groupAssistant.getEndTime();
                    if (endTime != null){
                        return  endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    }
                    return "9999-99-99";
                }
                break;
            case 4:
                // 靓号
                LuckyNumber luckyNumber = luckyNumberMapper.selectOne(new LambdaQueryWrapper<LuckyNumber>().eq(LuckyNumber::getUserId, tUser.getUid()).orderByDesc(LuckyNumber::getPurchaseTime).last("limit 1"));
                if (luckyNumber != null){
                    return "9999-99-99";
                }
                break;
        }
        return null;
    }

    @Override
    public MemberPackageDTO getInfo(Long id) {
        MemberPackageConfig memberPackageConfig = baseMapper.selectOne(new LambdaQueryWrapper<MemberPackageConfig>().eq(MemberPackageConfig::getId, id));
        MemberPackageDTO memberPackageDTO = new MemberPackageDTO();
        BeanUtils.copyProperties(memberPackageConfig, memberPackageDTO);
        memberPackageDTO.setPackageItems(memberItemService.getListByConfigId(memberPackageConfig.getId()));
        return memberPackageDTO;
    }

    @Override
    public int countList(MemberSearchVo searchVo) {
        return Math.toIntExact(baseMapper.selectCount(new LambdaQueryWrapper<MemberPackageConfig>()
            .eq(searchVo.getState() != null, MemberPackageConfig::getState, searchVo.getState())
            .eq(searchVo.getPackageType() != null, MemberPackageConfig::getPackageType, searchVo.getPackageType())
            .and(searchVo.getPackageName() != null && !searchVo.getPackageName().isEmpty(), w1 -> w1.like(MemberPackageConfig::getPackageName, searchVo.getPackageName()))
        ));
    }

    @Override
    public List<LuckyNumber> getLuckyNumberList(LuckyNumberVo vo) {
        LambdaQueryWrapper<LuckyNumber> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(vo.getKeyword())) {
            wrapper.and(w -> w.like(LuckyNumber::getPhoneNumber, vo.getKeyword())
                .or()
                .like(LuckyNumber::getUsername, vo.getKeyword()));
        }
        wrapper.orderByDesc(LuckyNumber::getCreateTime);
        return  luckyNumberMapper.selectList(wrapper);
    }

    @Override
    public int getLuckyNumberCount(LuckyNumberVo vo) {
        LambdaQueryWrapper<LuckyNumber> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(vo.getKeyword())) {
            wrapper.and(w -> w.like(LuckyNumber::getPhoneNumber, vo.getKeyword())
                .or()
                .like(LuckyNumber::getUsername, vo.getKeyword()));
        }
        Long count = luckyNumberMapper.selectCount(wrapper);
        return Math.toIntExact(count != null ? count : 0);
    }
}
